#ifndef CDRAWGAME_H
#define CDRAWGAME_H


#include "CDrawHand.h"
#include "CGame.h"
#include "csranks.h"
#include "CaribbeanCommon.h"
#include "CaribbeanDefs.h"

class CPokerConnection;
class CSavedGame;
class Shue;

//*************************************************************************************************
//
//  This class implements the game specific logic for Caribbean Draw.
//
//  Every hand of Caribbean Draw results in a new instance of this object being created.  When
//  that hand is completed, the game object is destroyed.
//
//  kharmon.  08-28-07.
//
//*************************************************************************************************
class CDrawGame : public CGame
{
public:
    // used for brand new games
    CDrawGame(CPokerConnection* pConn, int32 nBet, int32 nProgressiveBet);

    // used when restoring saved games
    CDrawGame(CPokerConnection*, CSavedGame*);

    virtual ~CDrawGame();

    int32 getDeckSeed() { return m_nDeckSeed; }

    // called when we need to deal the cards
    bool8 deal(int32 nBalance);

    // called when the user raises (aka calls)
    bool8 raise(int32 nBalance, uint8 *pucMsgBuf);

    // called when the user folds
    bool8 fold(int32 nBalance);

    // return the initial bet amount
    int32 getBet() { return m_nBet; }

    // called to tell us to send the "restored" state to the client
    void send();

    // theoretically called to tell us to load this game's state into the CSavedGame object.
    // in practice, does nothing.
    void save(CSavedGame *);

    // is the game instance up, working, and valid?
    bool8 isGameOK() { return m_bGameOK; }

    // accessors for getting the various cards
    CDrawHand * getPlayerHand() { return m_pPlayer;    }
    CDrawHand * getDealerHand() { return m_pDealer;    }

    // the cards the dealer was original given, before any draws were made
    CDrawHand* getOriginalDealerHand() { return m_pOrigDealer; }

    // Get the dealer and player drawn cards.
    Hand * getPlayerDraw() { return &m_drawnPlayerCards; }
    Hand * getDealerDraw() { return &m_drawnDealerCards; }


    enum PayTableTypes
    {
        CDRAW_PAYFREQ_NORMAL,
        MAX_CDRAW_PAY_FREQUENCIES
    };

    enum ProgressivePayTableTypes
    {
        CDRAW_PROGPAYFREQ_NORMAL,
        MAX_CDRAW_PROGRESSIVE_PAY_FREQUENCIES
    };


private:

    // does the work of restoring a game's saved state, called from constructor
    bool8 restore(CSavedGame* saved);

    // figures out how much money needs to be given to or taken from the user, and where it 
    // goes and comes from.
    bool8 calcPayouts(int32*, int32*, int32*, bool8, bool8*, int32*, int32*, uint8 *);

    // called by raise and fold to finish up the game, figure out the outcome,
    // and send the results to the database and to the client.
    bool8 finish(bool8, int32, uint8 *);

    CPokerConnection         *m_pConn;  // this game's connection back to the client.

    CDrawHand     *m_pOrigDealer;
    CDrawHand     *m_pDealer;         // the dealer's 2 cards
    CDrawHand     *m_pPlayer;         // the player's 2 cards

    bool8           m_bGameOK;          // game is ok?

    int32           m_nBet;             // player's initial bet
    int32           m_nProgressiveBet;  // did the user make a bet on the progressive?
    uint8           m_nPayTable;        // what paytable should we use?
    uint8           m_nProgPayTable;    // what progressive paytable should we use?

    int32           m_nDeckSeed;        // kharmon.  10-12-06.  #8226.  We now store the seed in the database.

    static CardMgr m_stdMgr;            // gotta have one of these for the Hand class

    static const int CDRAW_NUMDECKS;  // how many decks to deal out of...should just be 1

    static int32 m_anPayTable[MAX_CDRAW_PAY_FREQUENCIES][HR_ROYALFLUSH + 1];  // array of paytables...Draw only has 1 entry
    static int32 m_anProgressivePayTable[MAX_CDRAW_PROGRESSIVE_PAY_FREQUENCIES][HR_ROYALFLUSH + 1];   // array of progressive paytables...Draw only has 1 entry.

    Shue  *m_pShue;         // we deal the draw cards out of this.

    Hand  m_drawnDealerCards;   // The 0, 1, or 2 cards drawn by the dealer
    Hand  m_drawnPlayerCards;   // The 0, 1, or 2 cards drawn by the player

};


#endif